#pragma once

namespace gtl
{

namespace deleter
{

struct object
{
	template<class T>
	void operator()(T* ptr)
	{
		delete ptr;
	}
};

struct co_task_mem_free
{
	template<class T>
	void operator()(T* ptr)
	{
		CoTaskMemFree(ptr);
	}
};

struct global_free
{
	template<class T>
	void operator()(T* ptr)
	{
		GlobalFree(*ptr);
	}
};

struct c_free
{
	template<class T>
	void operator()(T* ptr)
	{
		free(ptr);
	}
};

struct array
{
	template<class T>
	void operator()(T* ptr)
	{
		delete[] ptr;
	}
};

struct handle
{
	template<class T>
	void operator()(T* ptr)
	{
		CloseHandle(*ptr);
		delete ptr;
	}
};

struct handle_ref
{
	template<class T>
	void operator()(T* ptr)
	{
		CloseHandle(*ptr);
	}
};

struct gdi_object
{
	template<class T>
	void operator()(T* ptr)
	{
		DeleteObject(*ptr);
		delete ptr;
	}
};

struct gdi_object_ref
{
	template<class T>
	void operator()(T* ptr)
	{
		DeleteObject(*ptr);
	}
};

struct c_file
{
	template<class T>
	void operator()(T* ptr)
	{
		fclose(ptr);
	}
};

struct file
{
	template<class T>
	void operator()(T* ptr)
	{
		ptr->Close();
		delete ptr;
	}
};

struct file_ref
{
	template<class T>
	void operator()(T* ptr)
	{
		ptr->Close();
	}
};

struct com
{
	template<class T>
	void operator()(T* ptr)
	{
		ptr->Release();
	}
};

} // end of namespace deleter

} // end of namespace gtl